package com.yang.thread;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.List;
import java.util.ArrayList;

/**
 * 高级多线程示例
 * 演示Future、CompletableFuture、原子类、显式锁等高级概念
 */
public class AdvancedThreadExample {
    
    public static void main(String[] args) {
        System.out.println("=== 高级多线程示例 ===");
        
        // 1. Future和Callable示例
        demonstrateFutureAndCallable();
        
        // 2. CompletableFuture示例
        demonstrateCompletableFuture();
        
        // 3. 原子类示例
        demonstrateAtomicClasses();
        
        // 4. 显式锁示例
        demonstrateExplicitLocks();
        
        // 5. 读写锁示例
        demonstrateReadWriteLock();
    }
    
    /**
     * Future和Callable示例
     */
    private static void demonstrateFutureAndCallable() {
        System.out.println("\n--- Future和Callable示例 ---");
        
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        // 提交Callable任务
        List<Future<Integer>> futures = new ArrayList<>();
        
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            Future<Integer> future = executor.submit(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    System.out.println("计算任务 " + taskId + " 开始执行");
                    Thread.sleep(2000 + (int)(Math.random() * 2000)); // 2-4秒随机延迟
                    
                    int result = taskId * taskId;
                    System.out.println("计算任务 " + taskId + " 完成，结果: " + result);
                    return result;
                }
            });
            
            futures.add(future);
        }
        
        // 获取结果
        System.out.println("等待所有计算任务完成...");
        int totalSum = 0;
        
        for (int i = 0; i < futures.size(); i++) {
            try {
                Integer result = futures.get(i).get(6, TimeUnit.SECONDS); // 最多等待6秒
                totalSum += result;
                System.out.println("任务 " + (i + 1) + " 结果: " + result);
            } catch (TimeoutException e) {
                System.out.println("任务 " + (i + 1) + " 超时");
                futures.get(i).cancel(true);
            } catch (Exception e) {
                System.out.println("任务 " + (i + 1) + " 执行异常: " + e.getMessage());
            }
        }
        
        System.out.println("所有任务总和: " + totalSum);
        executor.shutdown();
    }
    
    /**
     * CompletableFuture示例
     */
    private static void demonstrateCompletableFuture() {
        System.out.println("\n--- CompletableFuture示例 ---");
        
        // 异步执行任务
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "任务1结果";
        });
        
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            return "任务2结果";
        });
        
        // 组合多个CompletableFuture
        CompletableFuture<String> combinedFuture = future1.thenCombine(future2, (result1, result2) -> {
            return "组合结果: " + result1 + " + " + result2;
        });
        
        // 链式处理
        CompletableFuture<String> finalFuture = combinedFuture
            .thenApply(result -> result.toUpperCase())
            .thenApply(result -> "[处理后] " + result);
        
        try {
            String result = finalFuture.get(5, TimeUnit.SECONDS);
            System.out.println("CompletableFuture最终结果: " + result);
        } catch (Exception e) {
            System.out.println("CompletableFuture执行异常: " + e.getMessage());
        }
        
        // 异步执行多个任务并等待所有完成
        CompletableFuture<Void> allTasks = CompletableFuture.allOf(
            CompletableFuture.runAsync(() -> System.out.println("异步任务A完成")),
            CompletableFuture.runAsync(() -> System.out.println("异步任务B完成")),
            CompletableFuture.runAsync(() -> System.out.println("异步任务C完成"))
        );
        
        try {
            allTasks.get(3, TimeUnit.SECONDS);
            System.out.println("所有异步任务完成");
        } catch (Exception e) {
            System.out.println("异步任务执行异常: " + e.getMessage());
        }
    }
    
    /**
     * 原子类示例
     */
    private static void demonstrateAtomicClasses() {
        System.out.println("\n--- 原子类示例 ---");
        
        AtomicInteger atomicCounter = new AtomicInteger(0);
        int threadCount = 5;
        int incrementsPerThread = 1000;
        
        Thread[] threads = new Thread[threadCount];
        
        for (int i = 0; i < threadCount; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < incrementsPerThread; j++) {
                    atomicCounter.incrementAndGet(); // 原子递增操作
                }
            });
        }
        
        long startTime = System.currentTimeMillis();
        
        // 启动所有线程
        for (Thread thread : threads) {
            thread.start();
        }
        
        // 等待所有线程完成
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        long endTime = System.currentTimeMillis();
        
        System.out.println("原子类计数器结果:");
        System.out.println("期望值: " + (threadCount * incrementsPerThread));
        System.out.println("实际值: " + atomicCounter.get());
        System.out.println("执行时间: " + (endTime - startTime) + "ms");
        
        // 演示CAS操作
        AtomicInteger casDemo = new AtomicInteger(10);
        boolean success = casDemo.compareAndSet(10, 20);
        System.out.println("CAS操作成功: " + success + ", 当前值: " + casDemo.get());
        
        success = casDemo.compareAndSet(10, 30);
        System.out.println("CAS操作成功: " + success + ", 当前值: " + casDemo.get());
    }
    
    /**
     * 显式锁示例
     */
    private static void demonstrateExplicitLocks() {
        System.out.println("\n--- 显式锁示例 ---");
        
        BankAccountWithLock account = new BankAccountWithLock(1000);
        
        Thread[] threads = new Thread[3];
        for (int i = 0; i < 3; i++) {
            final int threadId = i + 1;
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 3; j++) {
                    double amount = 100 + Math.random() * 200;
                    account.withdraw(amount, "用户" + threadId);
                    
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }
            });
        }
        
        for (Thread thread : threads) {
            thread.start();
        }
        
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        System.out.println("显式锁示例结束，最终余额: " + account.getBalance());
    }
    
    /**
     * 读写锁示例
     */
    private static void demonstrateReadWriteLock() {
        System.out.println("\n--- 读写锁示例 ---");
        
        SharedData sharedData = new SharedData();
        
        // 创建多个读线程
        Thread[] readers = new Thread[3];
        for (int i = 0; i < 3; i++) {
            final int readerId = i + 1;
            readers[i] = new Thread(() -> {
                for (int j = 0; j < 5; j++) {
                    String data = sharedData.read("读者" + readerId);
                    System.out.println("读者" + readerId + " 读取到: " + data);
                    
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        return;
                    }
                }
            });
        }
        
        // 创建写线程
        Thread writer = new Thread(() -> {
            for (int i = 1; i <= 3; i++) {
                sharedData.write("数据版本" + i, "写者");
                
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return;
                }
            }
        });
        
        // 启动所有线程
        for (Thread reader : readers) {
            reader.start();
        }
        writer.start();
        
        // 等待所有线程完成
        for (Thread reader : readers) {
            try {
                reader.join();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        try {
            writer.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        System.out.println("读写锁示例结束");
    }
}

/**
 * 使用显式锁的银行账户
 */
class BankAccountWithLock {
    private double balance;
    private final ReentrantLock lock = new ReentrantLock();
    
    public BankAccountWithLock(double initialBalance) {
        this.balance = initialBalance;
    }
    
    public boolean withdraw(double amount, String user) {
        lock.lock(); // 获取锁
        try {
            System.out.println(user + " 尝试取款: " + amount + " [当前余额: " + balance + "]");
            
            if (balance >= amount) {
                Thread.sleep(100); // 模拟处理时间
                balance -= amount;
                System.out.println(user + " 取款成功: " + amount + " [剩余余额: " + balance + "]");
                return true;
            } else {
                System.out.println(user + " 取款失败: 余额不足");
                return false;
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        } finally {
            lock.unlock(); // 释放锁
        }
    }
    
    public double getBalance() {
        lock.lock();
        try {
            return balance;
        } finally {
            lock.unlock();
        }
    }
}

/**
 * 使用读写锁的共享数据
 */
class SharedData {
    private String data = "初始数据";
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    
    public String read(String readerName) {
        rwLock.readLock().lock(); // 获取读锁
        try {
            System.out.println(readerName + " 开始读取数据...");
            Thread.sleep(1000); // 模拟读取时间
            System.out.println(readerName + " 读取完成");
            return data;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return null;
        } finally {
            rwLock.readLock().unlock(); // 释放读锁
        }
    }
    
    public void write(String newData, String writerName) {
        rwLock.writeLock().lock(); // 获取写锁
        try {
            System.out.println(writerName + " 开始写入数据: " + newData);
            Thread.sleep(1500); // 模拟写入时间
            this.data = newData;
            System.out.println(writerName + " 写入完成: " + newData);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            rwLock.writeLock().unlock(); // 释放写锁
        }
    }
}
